#ifndef OTHELLO_CUT_H
#define OTHELLO_CUT_H

#include "Algoritmo.h"
#include "Nodo.h"


#include <iostream>
#include "assert.h"

using namespace std;

#define MAX(s,t)      ((s)>(t)?(s):(t))
#define MIN(s,t)      ((s)<(t)?(s):(t))
#define MAXVALUE      1000
#define DIM           36
#define N             6

class state_t {
protected:
    unsigned char t_;
    unsigned free_;
    unsigned pos_;
public:

    explicit state_t(unsigned char t = 6) : t_(t), free_(0), pos_(0) {
    } //explicit lo usa para forzar al compilador a que no cree una conversion implicita en el constructor :) F
    //getters F

    unsigned char t() const {
        return t_;
    }

    unsigned free() const {
        return free_;
    }

    unsigned pos() const {
        return pos_;
    }
    // F

    bool is_color(bool color, int pos) const {
        if (color)
            return pos < 4 ? t_ & (1 << pos) : pos_ & (1 << pos - 4);
        else
            return !(pos < 4 ? t_ & (1 << pos) : pos_ & (1 << pos - 4));
    }

    bool is_black(int pos) const {
        return is_color(true, pos);
    }

    bool is_white(int pos) const {
        return is_color(false, pos);
    }

    bool is_free(int pos) const {
        return pos < 4 ? false : !(free_ & (1 << pos - 4));
    }

    bool is_full() const {
        return ~free_ == 0;
    }

    unsigned value() const;
    bool terminal() const;
    bool outflank(bool color, int pos) const; // creo que esta funcion lo que hace es decir si la posicion se "desborda" o no F	

    bool is_black_move(int pos) const {
        return (pos == DIM) || outflank(true, pos);
    }

    bool is_white_move(int pos) const {
        return (pos == DIM) || outflank(false, pos);
    }

    void set_color(bool color, int pos);
    state_t move(bool color, int pos) const;

    state_t black_move(int pos) {
        return move(true, pos);
    }

    state_t white_move(int pos) {
        return move(false, pos);
    }

    bool operator<(const state_t &s) const {
        return (free_ < s.free_) || ((free_ == s.free_) && (pos_ < s.pos_));
    }
    void print(ostream &os, int depth) const;
    void print_bits(ostream &os) const;
};

#endif  /* ALFABETA_H */